package xyz.poke.business.tool.controller;

import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import xyz.poke.business.tool.common.PageResult;
import xyz.poke.business.tool.common.Response;
import xyz.poke.business.tool.constants.DbConstants;
import xyz.poke.business.tool.constants.ErrorConstants;
import xyz.poke.business.tool.convert.CategoryConvert;
import xyz.poke.business.tool.convert.TreeConvert;
import xyz.poke.business.tool.dto.TreeDTO;
import xyz.poke.business.tool.dto.UserDTO;
import xyz.poke.business.tool.entity.Category;
import xyz.poke.business.tool.enums.UserRoleEnum;
import xyz.poke.business.tool.param.CategoryParam;
import xyz.poke.business.tool.service.ICategoryService;
import xyz.poke.business.tool.utils.CheckerUtils;
import xyz.poke.business.tool.utils.ResponseUtils;
import xyz.poke.business.tool.utils.TreeUtils;
import xyz.poke.business.tool.utils.UserUtils;
import xyz.poke.business.tool.vo.CategoryVo;
import xyz.poke.business.tool.vo.TreeVo;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 类目表 前端控制器
 * </p>
 *
 * @author 迫壳
 * @since 2024-02-22
 */
@Controller
@RequestMapping("/category")
@ResponseBody
public class CategoryController {

    @Autowired
    private ICategoryService categoryService;

    @PostMapping("paging")
    public Response<PageResult<CategoryVo>> paging(@RequestBody CategoryParam param) {
        PageResult<Category> paging = categoryService.paging(param);
        return ResponseUtils.ok(CategoryConvert.INSTANCE.to(paging));
    }

    @GetMapping("getTree")
    public Response<List<TreeVo>> getTree() {
        UserDTO currentUser = UserUtils.getCurrentUser();
        UserUtils.validUserRole(currentUser, Lists.newArrayList(UserRoleEnum.ROOT));
        List<Category> list = categoryService.list(new QueryWrapper<Category>().eq(DbConstants.IS_DEL, false));
        if (CollectionUtils.isEmpty(list)) {
            return ResponseUtils.ok(Lists.newArrayList());
        }
        List<TreeDTO.NodeDTO> nodes = list.stream()
                .map(category -> new TreeDTO.NodeDTO(category.getCode(), category.getName(), category.getPCode(), false))
                .collect(Collectors.toList());
        TreeDTO treeDTO = TreeUtils.initTree(nodes);
        return ResponseUtils.ok(TreeConvert.INSTANCE.toVo(treeDTO).getChildren());
    }

    @PostMapping()
    public Response<Boolean> add(@RequestBody CategoryParam param) {
        this.commonValid(param);
        Category category = new Category();
        category.setCode(param.getCode());
        category.setName(param.getName());
        category.setPCode(param.getFatherCode());
        return ResponseUtils.ok(categoryService.save(category));
    }

    @PutMapping()
    public Response<Boolean> update(@RequestBody CategoryParam param) {
        CheckerUtils.notNull(param.getId(), ErrorConstants.ID_NOT_NULL);
        this.commonValid(param);
        Category category = new Category();
        category.setId(param.getId());
        category.setCode(param.getCode());
        category.setName(param.getName());
        category.setPCode(param.getFatherCode());
        return ResponseUtils.ok(categoryService.updateById(category));
    }

    @DeleteMapping("/{id}")
    public Response<Boolean> delete(@PathVariable(value = "id") Integer id) {
        CheckerUtils.notNull(id, ErrorConstants.ID_NOT_NULL);
        Category category = new Category();
        category.setId(id);
        category.setIsDel(true);
        return ResponseUtils.ok(categoryService.updateById(category));
    }

    private void commonValid(CategoryParam param) {
        CheckerUtils.notNull(param.getCode(), ErrorConstants.CODE_NOT_NULL);
        CheckerUtils.notNull(param.getName(), ErrorConstants.NAME_NOT_NULL);
        int count = categoryService.count(new QueryWrapper<Category>().eq(DbConstants.CODE, param.getCode()).eq(DbConstants.IS_DEL, false));
        CheckerUtils.isNotTrue(count >=1, ErrorConstants.CODE_EXIST);
    }

}
